package com.rongmei.jdsync.service.impl;

import com.rongmei.jdsync.entity.Category;
import com.rongmei.jdsync.entity.Goods;
import com.rongmei.jdsync.entity.GoodsDetail;
import com.rongmei.jdsync.repository.CategoryRepository;
import com.rongmei.jdsync.repository.GoodsDetailRepository;
import com.rongmei.jdsync.repository.GoodsRepository;
import com.rongmei.jdsync.service.GoodsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 商品服务实现类
 *
 * @author dongjun
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class GoodsServiceImpl implements GoodsService {

    private final GoodsDetailRepository goodsDetailRepository;
    private final GoodsRepository goodsRepository;
    @Autowired
    private CategoryRepository categoryRepository;

    /**
     * 查询所有商品
     *
     * @return 返回所有商品的列表
     */
    @Override
    public List<Goods> findGoodsAll() {
        log.info("开始查询所有商品");
        return goodsRepository.findAll();
    }


    /**
     * 导出商品分类数据到Excel
     *
     * @return Excel文件字节数组
     * @throws IOException 如果IO操作失败
     */
    @Override
    public byte[] exportCategoryToExcel() throws IOException {
        // 获取所有分类数据
        List<Category> categories = categoryRepository.findAll();
        log.info("获取到分类数据，共{}条记录", categories.size());

        // 按层级组织分类数据
        Map<Long, List<Category>> level1Map = categories.stream().filter(c -> c.getLevel() == 1).collect(Collectors.groupingBy(Category::getCategoryId));

        Map<Long, List<Category>> level2Map = categories.stream().filter(c -> c.getLevel() == 2).collect(Collectors.groupingBy(Category::getCategoryId1));

        Map<Long, List<Category>> level3Map = categories.stream().filter(c -> c.getLevel() == 3).collect(Collectors.groupingBy(Category::getCategoryId2));

        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("商品分类");

            // 创建表头
            Row headerRow = sheet.createRow(0);
            headerRow.createCell(0).setCellValue("一级分类");
            headerRow.createCell(1).setCellValue("二级分类");
            headerRow.createCell(2).setCellValue("三级分类");

            int rowNum = 1;

            // 遍历一级分类
            for (Map.Entry<Long, List<Category>> level1Entry : level1Map.entrySet()) {
                Category level1Cat = level1Entry.getValue().get(0);
                int level1StartRow = rowNum;
                int level1EndRow = rowNum;

                // 遍历当前一级分类下的二级分类
                List<Category> level2Cats = level2Map.getOrDefault(level1Cat.getCategoryId(), new ArrayList<>());
                for (Category level2Cat : level2Cats) {
                    int level2StartRow = rowNum;
                    int level2EndRow = rowNum;

                    // 遍历当前二级分类下的三级分类
                    List<Category> level3Cats = level3Map.getOrDefault(level2Cat.getCategoryId(), new ArrayList<>());
                    for (Category level3Cat : level3Cats) {
                        Row row = sheet.createRow(rowNum++);
                        row.createCell(0).setCellValue(level1Cat.getCategoryName());
                        row.createCell(1).setCellValue(level2Cat.getCategoryName());
                        row.createCell(2).setCellValue(level3Cat.getCategoryName());
                        level2EndRow++;
                        level1EndRow++;
                    }

                    // 合并二级分类单元格
                    if (level2StartRow < level2EndRow && (level2EndRow - level2StartRow) > 1) {
                        log.debug("合并二级分类单元格: 行范围[{}-{}]", level2StartRow, level2EndRow - 1);
                        sheet.addMergedRegion(new CellRangeAddress(level2StartRow, level2EndRow - 1, 1, 1));
                    } else {
                        log.debug("跳过二级分类单元格合并: 行范围[{}-{}]", level2StartRow, level2EndRow - 1);
                    }
                }

                // 合并一级分类单元格
                if (level1StartRow < level1EndRow && (level1EndRow - level1StartRow) > 1) {
                    log.debug("合并一级分类单元格: 行范围[{}-{}]", level1StartRow, level1EndRow - 1);
                    sheet.addMergedRegion(new CellRangeAddress(level1StartRow, level1EndRow - 1, 0, 0));
                } else {
                    log.debug("跳过一级分类单元格合并: 行范围[{}-{}]", level1StartRow, level1EndRow - 1);
                }
            }

            // 自动调整列宽
            for (int i = 0; i < 3; i++) {
                sheet.autoSizeColumn(i);
            }

            // 将工作簿写入输出流
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            workbook.write(outputStream);
            // 返回输出流的字节数组
            return outputStream.toByteArray();
        }
    }

    // 保留文件其余部分不变...
    @Override
    public void downloadGoodsImages() {
        // 原有实现保持不变...
    }


    @Override
    public byte[] exportGoodsToExcel() throws IOException {
        log.info("开始导出商品数据到Excel");
        long startTime = System.currentTimeMillis();

        // 1. 获取所有商品数据
        List<Goods> goodsList = findGoodsAll();
        log.info("共获取到{}条商品数据", goodsList.size());

    // 2. 批量获取商品详情和分类信息
        List<Integer> goodsIds = goodsList.stream().map(goods -> goods.getGoodsId().intValue()).collect(Collectors.toList());
        List<GoodsDetail> goodsDetails = goodsDetailRepository.findAllById(goodsIds);
        Map<Integer, GoodsDetail> goodsDetailMap = goodsDetails.stream().collect(Collectors.toMap(GoodsDetail::getGoodsId, detail -> detail));

        List<Category> categories = categoryRepository.findAll();
        Map<Long, Category> categoryMap = categories.stream().collect(Collectors.toMap(Category::getCategoryId, category -> category));

        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("商品列表");

            // 创建表头
            Row headerRow = sheet.createRow(0);
            headerRow.createCell(0).setCellValue("商品编码");
            headerRow.createCell(1).setCellValue("商品名称");
            headerRow.createCell(2).setCellValue("商品分类");
            headerRow.createCell(3).setCellValue("商品价格");
            headerRow.createCell(4).setCellValue("划线价");
            headerRow.createCell(5).setCellValue("外链地址");
            headerRow.createCell(6).setCellValue("图片地址");

            // 3. 使用线程池并行处理数据填充
            int threadCount = Runtime.getRuntime().availableProcessors() * 2;
            ExecutorService executor = Executors.newFixedThreadPool(threadCount);
            // 动态计算批次大小
            int chunkSize = Math.max(100, goodsList.size() / threadCount);

            log.info("使用{}个线程并行处理，每批处理{}条记录", threadCount, chunkSize);

            // 创建锁对象用于同步
            final Object lock = new Object();

            for (int i = 0; i < goodsList.size(); i += chunkSize) {
                final int start = i;
                final int end = Math.min(i + chunkSize, goodsList.size());

                executor.execute(() -> {
                    for (int j = start; j < end; j++) {
                        Goods goods = goodsList.get(j);

                        // 同步创建行和单元格
                        synchronized (lock) {
                            Row row = sheet.createRow(j + 1); // +1跳过表头

                            // 填充商品基本信息
                            row.createCell(0).setCellValue(goods.getGoodsId() != null ? goods.getGoodsId().toString() : "");
                            row.createCell(1).setCellValue(goods.getGoodsName() != null ? goods.getGoodsName() : "");

                            // 填充分类信息
                            String categoryName = "";
                            GoodsDetail goodsDetail = goodsDetailMap.get(goods.getGoodsId().intValue());
                            if (goodsDetail != null && goodsDetail.getCategoryId() != null) {
                                Category category = categoryMap.get(goodsDetail.getCategoryId());
                                if (category != null) {
                                    Category level1 = categoryMap.get(category.getCategoryId1());
                                    Category level2 = categoryMap.get(category.getCategoryId2());
                                    Category level3 = categoryMap.get(category.getCategoryId3());

                                    if (level1 != null) {
                                        categoryName += level1.getCategoryName();
                                    }
                                    if (level2 != null) {
                                        categoryName += "/" + level2.getCategoryName();
                                    }
                                    if (level3 != null) {
                                        categoryName += "/" + level3.getCategoryName();
                                    }
                                }
                            }
                            row.createCell(2).setCellValue(categoryName);

                            // 填充价格信息
                            row.createCell(3).setCellValue(goods.getPrice() != null ? goods.getPrice().toString() : "");
                            row.createCell(4).setCellValue(goods.getMarketPrice() != null ? goods.getMarketPrice().toString() : "");
                            row.createCell(5).setCellValue("http://bhh5.jdev.beyondin.com/#/views/goods/goods_detail?id=" + goods.getGoodsId());
                            row.createCell(6).setCellValue(goods.getGoodsImage());
                        }
                    }
                });
            }

            // 等待所有任务完成
            executor.shutdown();
            while (!executor.isTerminated()) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    log.warn("线程被中断", e);
                }
            }

            // 自动调整列宽
            for (int i = 0; i < 6; i++) {
                sheet.autoSizeColumn(i);
            }

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            workbook.write(outputStream);

            long endTime = System.currentTimeMillis();
            log.info("商品数据导出完成，共耗时{}毫秒", (endTime - startTime));
            return outputStream.toByteArray();
        }
    }

    /**
     * 根据页码和每页大小分页查询商品列表
     *
     * @param pageNum 页码，从1开始计数
     * @param pageSize 每页显示的商品数量
     * @return 分页后的商品列表
     */
    @Override
    public List<Goods> findGoodsByPage(int pageNum, int pageSize) {
        log.info("分页查询商品，页码: {}, 每页大小: {}", pageNum, pageSize);
        PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize);
        return goodsRepository.findAll(pageRequest).getContent();
    }
}
